/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.treeeditpart;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.views.properties.IPropertySource;

import com.cea.papyrus.core.actions.CloseDiagramAction;
import com.cea.papyrus.core.actions.OpenDiagramAction;
import com.cea.papyrus.core.actions.delete.DeleteFromModelAction;
import com.cea.papyrus.core.commands.diagram.CloseDiagramCommand;
import com.cea.papyrus.core.commands.diagram.DiagramDeleteCommand;
import com.cea.papyrus.core.commands.diagram.OpenDiagramCommand;
import com.cea.papyrus.core.editor.ModelManager;
import com.cea.papyrus.core.editor.MultiDiagramEditor;
import com.cea.papyrus.core.editpart.IUMLDiagramElementEditPart;
import com.cea.papyrus.core.ui.properties.advanced.EObjectPropertySource;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;

/**
 * this class represents the element diagram in the outline
 */
public class DiagramTreeEditPart extends CommonTreeEditPart
implements PropertyChangeListener, IUMLDiagramElementEditPart {

	/**
	 * the diagram element
	 */
	private Diagram diagram= null;

	/**
	 * 
	 */
	private IPropertySource propertySource;

	/**
	 * a listener
	 */
	private GefUMLAdapter _adapter = new GefUMLAdapter();

	/**
	 * 
	 */
	private ElementTreeEditPart editPartOwner;

	/**
	 * Create a new instance of this edit part using the given model element.
	 * 
	 * @param element a non-null ShapesDiagram instance
	 * @param modelManager 
	 * @param context 
	 */
	DiagramTreeEditPart(Diagram element,ModelManager modelManager, ElementTreeEditPart context) {
		super(element, modelManager);
		this.diagram = element;
		editPartOwner = context;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractEditPart#activate()
	 */
	@Override
	public void activate() {
		super.activate();
		((Notifier) getDiagram()).eAdapters().add(_adapter);
		editPartOwner.addDiagramListeners(this);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractEditPart#deactivate()
	 */
	@Override
	public void deactivate() {
		super.deactivate();
		((Notifier)getDiagram()).eAdapters().remove(_adapter);
		editPartOwner.removeDiagramListeners(this);
	}

//	/* (non-Javadoc)
//	 * @see com.cea.papyrus.core.common.treeeditpart.CommonTreeEditPart#getImage()
//	 */
//	@Override
//	public Image getImage() {
//		return PapyrusPlugin.UML_SHORT_LABEL_PROVIDER.getImage(this);
//	}
	
	/**
	 * 
	 * 
	 * @return the Diagram associated to this treeEditPart
	 */
	public Diagram getDiagram(){
		return diagram;
	}
	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	/**
	 * 
	 * 
	 * @param key 
	 * 
	 * @return 
	 */
	@Override
	public Object getAdapter(Class key) {
		if (IPropertySource.class == key) {
			return getPropertySource();
		}
		return super.getAdapter( key );
	}

	/**
	 * 
	 * 
	 * @return 
	 */
	protected IPropertySource getPropertySource() {
		if( propertySource == null ) {
			propertySource = new EObjectPropertySource( this.getDiagram());
		}
		return propertySource;
	}

	/* (non-Javadoc)
	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
	 */
	/**
	 * 
	 * 
	 * @param evt 
	 */
	public void propertyChange(PropertyChangeEvent evt) {
		String prop = evt.getPropertyName();
	}
	/* (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractEditPart#getCommand(org.eclipse.gef.Request)
	 */
	/**
	 * 
	 * 
	 * @param request 
	 * 
	 * @return 
	 */
	@Override
	public Command getCommand(Request request) {
		Diagram diagram = getDiagram();
		CompoundCommand command = new CompoundCommand();
		if(DeleteFromModelAction.DELETE_FROM_MODEL_ACTION_REQUEST.equals(request.getType())) {
			command.add(new DiagramDeleteCommand(diagram,this.getModelManager() ));
			return command;
		}
		if(CloseDiagramAction.CLOSE_DIAGRAM_ACTION_REQUEST.equals(request.getType())) {
			command.add(new CloseDiagramCommand(diagram));
			return command;
		}
		if(OpenDiagramAction.OPEN_DIAGRAM_ACTION_REQUEST.equals(request.getType())) {
			// check if it is already open.
			// if it is not open, open it
			// If it is already open, just make it visible in the editor
			if(!diagram.isIsVisible()) {
				command.add(new OpenDiagramCommand(diagram));
			} else {
				IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
				if(part instanceof MultiDiagramEditor) {
					// try to find the corresponding editor
					((MultiDiagramEditor)part).setActiveEditor(diagram);
				}
			}
			return command;
		}
		return super.getCommand(request);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractEditPart#performRequest(org.eclipse.gef.Request)
	 */
	@Override
	public void performRequest(Request req) {
		final Command command = getCommand(req);
		if(command !=null) {
			BusyIndicator.showWhile(Display.getCurrent(), new Runnable() {
				/* (non-Javadoc)
				 * @see java.lang.Runnable#run()
				 */
				public void run() {
					getViewer().getEditDomain().getCommandStack().execute(command);
				}
			});

		}
	}


	/**
	 * 
	 */
	class GefUMLAdapter implements Adapter {

		/**
		 * 
		 */
		private Notifier _target;

		/**
		 * 
		 * 
		 * @param notification 
		 * 
		 * @see org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common.notify.Notification)
		 */
		public void notifyChanged(Notification notification) {
			if (notification.getEventType() != Notification.REMOVING_ADAPTER) {
				modelManager.modifGraphElement(getDiagram());
				refresh();
			}
		}

		/**
		 * 
		 * 
		 * @return 
		 * 
		 * @see org.eclipse.emf.common.notify.Adapter#getTarget()
		 */
		public Notifier getTarget() {
			return _target;
		}

		/**
		 * 
		 * 
		 * @param newTarget 
		 * 
		 * @see org.eclipse.emf.common.notify.Adapter#setTarget(org.eclipse.emf.common.notify.Notifier)
		 */
		public void setTarget(Notifier newTarget) {
			_target = newTarget;
		}

		/**
		 * 
		 * 
		 * @param type 
		 * 
		 * @return 
		 * 
		 * @see org.eclipse.emf.common.notify.Adapter#isAdapterForType(java.lang.Object)
		 */
		public boolean isAdapterForType(Object type) {
			return type.equals(getModel().getClass());
		}
	}

}


